﻿// /*------------------------------------------------------------
// 工程名:    Ensemble2D
// 文件名:    EnsembleApp.cs
// 编写人:    yhh
// 编写日期: 下午 5:29
// -------------------------------------------------------------*/

using System;
using System.Diagnostics;
using System.Linq;
using NLog;

namespace Ensemble
{
    public class EnsembleApp
    {
        private static readonly Logger logger = LogManager.GetCurrentClassLogger();

        public const string CmdArgDebug = "debug";
        public const string CmdArgEditor = "editor";
        public const string CmdArgProfiling = "profile";
        public const string PluginDirectory = "Plugins";
        public const string DataDirectory = "Data";

        public static CorePluginManager PluginManager { get; set; }
        public static event EventHandler UserDataChanged = null;
        public static event EventHandler AppDataChanged = null;

        private static bool initialized = false;
        private static bool runFromEditor = false;
        private static ExecutionEnvironment environment = ExecutionEnvironment.Unknown;
        private static ExecutionContext execContext = ExecutionContext.Terminated;
        private static IPluginLoader pluginLoader = null;
        private static EnsembleUserData userData = null;
        private static EnsembleAppData appData = null;
        private static IGraphicsBackend graphicsBack = null;
        private static bool isUpdating = false;
        private static bool terminateScheduled = false;

        public enum ExecutionEnvironment
        {
            Unknown,
            Launcher,
            Editor,
        }

        public enum ExecutionContext
        {
            /// <summary>
            /// 终止
            /// </summary>
            Terminated,
            Unknown,
            Game,
            Editor,
        }

        public static EnsembleUserData UserData
        {
            get { return userData; }
            set
            {
                userData = value ?? new EnsembleUserData();
                OnUserDataChanged();
            }
        }

        public static EnsembleAppData AppData
        {
            get { return appData; }
            set
            {
                appData = value ?? new EnsembleAppData();
                OnAppDataChanged();
            }
        }

        private static void OnAppDataChanged()
        {
            if (AppDataChanged != null)
                AppDataChanged(null, EventArgs.Empty);
        }

        private static void OnUserDataChanged()
        {
            if (UserDataChanged != null)
                UserDataChanged(null, EventArgs.Empty);
        }

        public static INativeWindow OpenWindow(WindowOptions options)
        {
            if (!initialized) throw new InvalidOperationException("无法初始化图形 / 渲染因为ES引擎自身无法初始化");

            logger.Info("打开窗体...");
            var window = graphicsBack.CreateWindow(options);

            InitPostWindow();

            return window;
        }

        public static void Init(ExecutionEnvironment env,ExecutionContext context,IPluginLoader plugins,string[] commandLineArgs)
        {
            if (initialized) return;

            if (commandLineArgs != null)
            {
                if (commandLineArgs.Contains(CmdArgDebug)) Debugger.Launch();

                if (commandLineArgs.Contains(CmdArgEditor)) runFromEditor = true;
            }

            environment = env;
            execContext = context;

            pluginLoader = plugins ?? new DummyPluginLoader();
            logger.Info("使用 '{0}' 加载插件", pluginLoader.GetType().Name);

            pluginLoader.Init();

            initialized = true;

            logger.Info("EnsembleApp初始化" + Environment.NewLine +
                "调试模式: {0}" + Environment.NewLine +
                "命令行参数: {1}",
                Debugger.IsAttached,
                commandLineArgs != null ? commandLineArgs.ToString(", ") : "null");
        }

        public static void Terminate()
        {
            if (!initialized) return;
            if (isUpdating)
            {
                terminateScheduled = true;
                return;
            }

            if (environment == ExecutionEnvironment.Editor && execContext == ExecutionContext.Game)
            {

            }
        }

        public static void InitPostWindow()
        {
            ContentProvider.InitDefaultContent();
        }
    }
}